package org.pms.demo.webservice.utils;

import net.sf.json.JSONObject;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ser.CustomSerializerFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.pms.demo.webservice.dao.RedisUtil;
import org.pms.demo.webservice.sign.RSA;

import java.io.*;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by xusaike on 17/5/31.
 */
public class ProjectUtils {



    /**
     * 格式化错误信息
     * @param key
     * @return
     */
    public static String getErrorMsg(String key){
        String msg = key;
        Map<String,Object> tokenMap = new HashMap();
        tokenMap.put("code",403);
        if("error".equals(key)){
            msg = "服务器错误";
        }else if("login".equals(key)){
            msg = "用户未登录";
        }else if("param".equals(key)){
            msg = "参数错误";
        }else if("unauthorized".equals(key)){
            msg = "您没有权限";
        }
        tokenMap.put("msg",msg);
        tokenMap.put("key",key);
        return beanToJson(tokenMap);

    }
    public static String getContentMsg(Object Object){
        return getContentMsg(Object,new HashMap());
    }
    public static String getContentMsg(Object Object,Map<String,Object> tokenMap){
        if(tokenMap==null){
            tokenMap = new HashMap();
        }
        tokenMap.put("code",200);
        tokenMap.put("content",Object);
        return beanToJson(tokenMap);

    }
    /**
     * 进行sql注入处理
     * @Title: preventInjection
     * @param param
     * @return
     * @return String
     * @throws
     */
    public static String preventInjection(String param){
        String regex = "select|update|delete|exec|count|'|\"|=|;|>|<|%/i";
        //String regex = "/\+|\*|\`|\/|\-|\$|\#|\^|\!|\@|\%|\&|\~|\^|\[|\]|\'|\"/";
        if(!StringUtils.isNullOrEmpty(param)){
            param = param.replaceAll(regex, "");
        }
        return param;
    }
    public static void inputstreamtofile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取x位随机数
     * @Title: getRandom
     * @return
     * @return int
     * @throws
     */
    public static String getRandomForSix(){
        Random rad = new Random();
        return StringUtils.getStringSix(rad.nextInt(1000000));
    }

    /**
     * xml字符串转换成bean对象
     *
     * @param xmlStr xml字符串
     * @param clazz 待转换的class
     * @return 转换后的对象
     */
    public static Object xmlStrToBean(String xmlStr, Class<?> clazz) {
        Object obj = null;
        try {
            // 将xml格式的数据转换成Map对象
            Map<String, Object> map = xmlStrToMap(xmlStr);
            //将map对象的数据转换成Bean对象
            obj = mapToBean(map, clazz);
        } catch(Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 将xml格式的字符串转换成Map对象
     *
     * @param xmlStr xml格式的字符串
     * @return Map对象
     * @throws Exception 异常
     */
    public static Map<String, Object> xmlStrToMap(String xmlStr) throws Exception {
        if(StringUtils.isNullOrEmpty(xmlStr)) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        //将xml格式的字符串转换成Document对象
        Document doc = DocumentHelper.parseText(xmlStr);
        //获取根节点
        Element root = doc.getRootElement();
        //获取根节点下的所有元素
        List<?> children = root.elements();
        //循环所有子元素
        if(children != null && children.size() > 0) {
            for(int i = 0; i < children.size(); i++) {
                Element child = (Element)children.get(i);
                map.put(child.getName(), child.getTextTrim());
            }
        }
        return map;
    }

    /**
     * 将Map对象通过反射机制转换成Bean对象
     *
     * @param map 存放数据的map对象
     * @param clazz 待转换的class
     * @return 转换后的Bean对象
     * @throws Exception 异常
     */
    public static Object mapToBean(Map<String, Object> map, Class<?> clazz) throws Exception {
        Object obj = clazz.newInstance();
        if(map != null && map.size() > 0) {
            for(Map.Entry<String, Object> entry : map.entrySet()) {
                String propertyName = entry.getKey();
                Object value = entry.getValue();
                String setMethodName = "set"
                        + propertyName.substring(0, 1).toUpperCase()
                        + propertyName.substring(1);
                Field field = getClassField(clazz, propertyName);
                Class<?> fieldTypeClass = field.getType();
                value = convertValType(value, fieldTypeClass);
                clazz.getMethod(setMethodName, field.getType()).invoke(obj, value);
            }
        }
        return obj;
    }

    /**
     * 将Object类型的值，转换成bean对象属性里对应的类型值
     *
     * @param value Object对象值
     * @param fieldTypeClass 属性的类型
     * @return 转换后的值
     */
    private static Object convertValType(Object value, Class<?> fieldTypeClass) {
        Object retVal = null;
        if(Long.class.getName().equals(fieldTypeClass.getName())
                || long.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Long.parseLong(value.toString());
        } else if(Integer.class.getName().equals(fieldTypeClass.getName())
                || int.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Integer.parseInt(value.toString());
        } else if(Float.class.getName().equals(fieldTypeClass.getName())
                || float.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Float.parseFloat(value.toString());
        } else if(Double.class.getName().equals(fieldTypeClass.getName())
                || double.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Double.parseDouble(value.toString());
        } else {
            retVal = value;
        }
        return retVal;
    }

    /**
     * 获取指定字段名称查找在class中的对应的Field对象(包括查找父类)
     *
     * @param clazz 指定的class
     * @param fieldName 字段名称
     * @return Field对象
     */
    private static Field getClassField(Class<?> clazz, String fieldName) {
        if( Object.class.getName().equals(clazz.getName())) {
            return null;
        }
        Field []declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.getName().equals(fieldName)) {
                return field;
            }
        }

        Class<?> superClass = clazz.getSuperclass();
        if(superClass != null) {// 简单的递归一下
            return getClassField(superClass, fieldName);
        }
        return null;
    }













    /**
     * bean转换成json(Unicode编码)
     * @Title: beanToJson
     * @param o
     * @return
     * @returnType String
     * @throws
     */
    public static String beanToJson(Object o){
        String str="";
        if(null==o||"".equals(o)){
            return str;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        //使Jackson JSON支持Unicode编码非ASCII字符
        CustomSerializerFactory serializerFactory= new CustomSerializerFactory();
        serializerFactory.addSpecificMapping(String.class, new StringUnicodeSerializer());
        objectMapper.setSerializerFactory(serializerFactory);
        try {
            str=objectMapper.writeValueAsString(o);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        str = str.replaceAll("/", "\\\\/");

        return str;
    }


    /**
     * 泛型排序：必须实现Comparable接口
     * @Title: quickSort
     * @param in
     * @param begin
     * @param end
     * @returnType void
     * @throws
     */
    @SuppressWarnings("unchecked")
    private static void quickSort(Object[] in,int begin, int end) {
        if( begin == end || begin == (end-1) ) return;
        Object p = in[begin];
        int a = begin +1;
        int b = a;
        for( ; b < end; b++) {
            //该对象类型数组必须实现Comparable接口，这样才能使用compareTo函数进行比较
            if( ((Comparable<Object>)in[b]).compareTo(p) < 0) {
                if(a == b){a++; continue;}
                Object temp = in[a];
                in[a] = in[b];
                in[b] = temp;
                a++;
            }
        }
        in[begin] = in[a-1];
        in[a-1] = p;
        if( a-1 > begin){
            quickSort(in,begin, a);
        }
        if( end-1 > a ) {
            quickSort(in,a, end);
        }
        return;
    }

    /**
     * 使用泛型，对任意对象数组排序，该对象类型数组必须实现Comparable接口
     * @Title: sort
     * @param input
     * @returnType void
     * @throws
     */
    public static <T extends Comparable<? super T>> void sort(T[] input){
        quickSort(input,0,input.length);
    }

    /**
     * List对象进行排序的功能，参考了Java中的Java.util.Collections类的sort()函数
     * @Title: sort
     * @param list
     * @returnType void
     * @throws
     */
    @SuppressWarnings("unchecked")
    public static <T > void sort(List<T> list){
        Object[] t = list.toArray();//将列表转换为数组
        quickSort(t,0,t.length); //对数组进行排序
        //数组排序完成后再写回到列表中
        ListIterator<T> i = list.listIterator();
        for (int j=0; j<t.length; j++) {
            i.next();
            i.set((T)t[j]);
        }
    }

    /**
     * int[]数组的重载函数
     * @Title: sort
     * @param input
     * @returnType void
     * @throws
     */
    public static void sort(int[] input){
        Integer[] t = new Integer[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];//封装
        }
        quickSort(t,0,t.length);//排序
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];//解封装
        }
    }
    /**
     * double[]数组的重载函数
     * @Title: sort
     * @param input
     * @returnType void
     * @throws
     */
    public static void sort(double[] input){
        Double[] t = new Double[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }
    /**
     * byte[]数组的重载函数
     * @Title: sort
     * @param input
     * @returnType void
     * @throws
     */
    public static void sort(byte[] input){
        Byte[] t = new Byte[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }
    /**
     * short[]数组的重载函数
     * @Title: sort
     * @param input
     * @returnType void
     * @throws
     */
    public static void sort(short[] input){
        Short[] t = new Short[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }
    /**
     * char[]数组的重载函数
     * @Title: sort
     * @param input
     * @returnType void
     * @throws
     */
    public static void sort(char[] input){
        Character[] t = new Character[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }
    /**
     * float[]数组的重载函数
     * @Title: sort
     * @param input
     * @returnType void
     * @throws
     */
    public static void sort(float[] input){
        Float[] t = new Float[input.length];
        for(int i = 0; i < input.length; i++){
            t[i] = input[i];
        }
        quickSort(t,0,t.length);
        for(int i = 0; i < input.length; i++){
            input[i] = t[i];
        }
    }

    /**
     * 使用 Map按key进行排序
     * @param map
     * @return
     */
    public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }

        Map<String, Object> sortMap = new TreeMap<String, Object>(
                new MapKeyComparator());

        sortMap.putAll(map);
        return sortMap;
    }
}
